<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>组织架构图</title>
        <script src="https://d3js.org/d3.v7.min.js"></script>
        <style>
            .node {
                cursor: pointer;
            }
            .node rect {
                stroke-width: 1px;
            }
            .node text {
                font-size: 12px;
                font-family: Arial, sans-serif;
            }
            .link {
                fill: none;
                stroke: #000000;
                stroke-width: 1px;
            }
            .avatar {
                width: 40px;
                height: 40px;
                border-radius: 50%;
            }
        </style>
    </head>
    <body>
        <div id="org-chart"></div>
        <script>
            // 组织数据
            const data = {
                name: "Dinosaur",
                title: "董事长",
                subtitle: "甲壳科技公司",
                avatar: "https://via.placeholder.com/40",
                children: [
                    {
                        name: "Anson",
                        title: "工程部总监",
                        subtitle: "工程部",
                        avatar: "https://via.placeholder.com/40",
                    },
                    {
                        name: "Ada",
                        title: "营销部总监",
                        subtitle: "营销部",
                        avatar: "https://via.placeholder.com/40",
                    },
                    {
                        name: "Linda",
                        title: "设计部总监",
                        subtitle: "设计部",
                        avatar: "https://via.placeholder.com/40",
                    },
                    {
                        name: "Paul",
                        title: "财务部总监",
                        subtitle: "财务部",
                        avatar: "https://via.placeholder.com/40",
                    },
                ],
            };

            // 设置画布尺寸
            const width = 1000;
            const height = 600;
            const nodeWidth = 120;
            const nodeHeight = 100;

            // 创建SVG
            const svg = d3
                .select("#org-chart")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

            // 创建树形布局
            const tree = d3.tree().nodeSize([nodeWidth * 1.5, nodeHeight * 2]);

            // 转换数据为层次结构
            const root = d3.hierarchy(data);

            // 计算节点位置
            tree(root);

            // 创建一个g元素作为容器，并移动到中心位置
            const g = svg
                .append("g")
                .attr("transform", `translate(${width / 2},50)`);

            // 绘制连接线
            g.selectAll(".link")
                .data(root.links())
                .join("path")
                .attr("class", "link")
                .attr("d", (d) => {
                    const sourceY = d.source.y + nodeHeight; // 从源节点底部开始
                    const targetY = d.target.y; // 直接连到目标节点顶部
                    const middleY = (sourceY + targetY) / 2;

                    return `M${d.source.x},${sourceY}
                            L${d.source.x},${middleY}
                            L${d.target.x},${middleY}
                            L${d.target.x},${targetY}`;
                });

            // 创建节点
            const node = g
                .selectAll(".node")
                .data(root.descendants())
                .join("g")
                .attr("class", "node")
                .attr(
                    "transform",
                    (d) => `translate(${d.x - nodeWidth / 2},${d.y})`
                );

            // 添加节点背景
            node.append("rect")
                .attr("width", nodeWidth)
                .attr("height", nodeHeight)
                .attr("rx", 5)
                .attr("ry", 5)
                .style("fill", (d) => (d.depth === 0 ? "#fff7e6" : "#f0f9ff"))
                .style("stroke", (d) =>
                    d.depth === 0 ? "#fa8c16" : "#1890ff"
                );

            // 添加头像
            node.append("foreignObject")
                .attr("x", nodeWidth / 2 - 20)
                .attr("y", 10)
                .attr("width", 40)
                .attr("height", 40)
                .html((d) => `<img src="${d.data.avatar}" class="avatar"/>`);

            // 添加名字
            node.append("text")
                .attr("x", nodeWidth / 2)
                .attr("y", 65)
                .attr("text-anchor", "middle")
                .text((d) => d.data.name);

            // 添加职位
            node.append("text")
                .attr("x", nodeWidth / 2)
                .attr("y", 80)
                .attr("text-anchor", "middle")
                .style("font-size", "10px")
                .style("fill", "#666")
                .text((d) => d.data.title);

            // 添加部门
            node.append("text")
                .attr("x", nodeWidth / 2)
                .attr("y", 92)
                .attr("text-anchor", "middle")
                .style("font-size", "10px")
                .style("fill", "#666")
                .text((d) => d.data.subtitle);
        </script>
    </body>
</html>
